package ace.tool.generate.code.impl.resolver.scheme.impl;

import ace.tool.generate.code.impl.generator.util.GeneratorUtils;
import ace.tool.generate.code.impl.resolver.TemplateModelClassResolver;
import ace.tool.generate.code.impl.resolver.impl.TemplateModelDataJdbcClassResolverImpl;
import ace.tool.generate.code.impl.resolver.model.TemplateModel;
import ace.tool.generate.code.impl.resolver.scheme.EntityClassSchemeResolver;
import ace.tool.generate.code.impl.resolver.scheme.model.EntityClassSchemeInput;
import ace.tool.generate.code.impl.resolver.scheme.model.EntityClassSchemeModel;
import org.apache.commons.text.WordUtils;

/**
 * @author caspar
 * @date 2023/11/17 10:34
 */
public class EntityClassSchemeResolverImpl implements EntityClassSchemeResolver {

  private final TemplateModelClassResolver resolver = new TemplateModelDataJdbcClassResolverImpl();

  @Override
  public EntityClassSchemeModel resolve(EntityClassSchemeInput input) {
    TemplateModel templateModel = resolver.resolve(input.getParams());
    EntityClassSchemeModel model =
        EntityClassSchemeModel.builder()
            .entityClassName(input.getParams().getSimpleName())
            .entityClassFullName(input.getParams().getName())
            .entityIdType(this.getEntityIdType(templateModel))
            .dtoClassName(this.getDtoClassName(input))
            .dtoClassFullName(this.getDtoClassFullName(input))
            .dtoPackageFullName(this.getDtoPackageFullName(input))
            .apiClassName(this.getApiClassName(input))
            .apiClassFullName(this.getApiClassFullName(input))
            .apiPackageFullName(this.getApiPackageFullName(input))
            .feignApiClassName(this.getFeignApiClassName(input))
            .feignApiClassFullName(this.getFeignApiClassFullName(input))
            .feignApiPackageFullName(this.getFeignApiPackageFullName(input))
            .feignClassName(this.getFeignClassName(input))
            .feignClassFullName(this.getFeignClassFullName(input))
            .feignPackageFullName(this.getFeignPackageFullName(input))
            .feignConfigPrefix(input.getFeignConfigPrefix())
            .namespace(this.getNamespace(input))
            .feignFirstLowercaseClassName(this.getFeignFirstLowercaseClassName(input))
            .restRpcControllerClassName(this.getRestRpcControllerClassName(input))
            .restRpcControllerClassFullName(this.getRestSdkControllerClassFullName(input))
            .restRpcControllerPackageFullName(this.getRestSdkControllerPackageFullName(input))
            .managerClassName(this.getManagerClassName(input))
            .managerClassFullName(this.getManagerClassFullName(input))
            .managerPackageFullName(this.getManagerPackageFullName(input))
            .managerImplClassName(this.getManagerImplClassName(input))
            .managerImplClassFullName(this.getManagerImplClassFullName(input))
            .managerImplPackageFullName(this.getManagerImplPackageFullName(input))
            .remark(templateModel.getRemark())
            //  .indexes(templateModel.getIndexes())
            .entityClassLowercaseDashName(this.getEntityClassLowercaseDashName(input))
            .build();
    return model;
  }

  private String getManagerImplPackageFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format("%s%s", basePackageName, input.getManagerImplPackageSuffix());
  }

  private String getManagerImplClassFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format(
        "%s%s.%s",
        basePackageName, input.getManagerImplPackageSuffix(), this.getManagerImplClassName(input));
  }

  private String getManagerImplClassName(EntityClassSchemeInput input) {
    return String.format(
        "%s%s", input.getParams().getSimpleName(), input.getManagerImplClassNameSuffix());
  }

  private String getManagerPackageFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format("%s%s", basePackageName, input.getManagerPackageSuffix());
  }

  private String getManagerClassFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format(
        "%s%s.%s",
        basePackageName, input.getManagerPackageSuffix(), this.getManagerClassName(input));
  }

  private String getManagerClassName(EntityClassSchemeInput input) {
    return String.format(
        "%s%s", input.getParams().getSimpleName(), input.getManagerClassNameSuffix());
  }

  private String getFeignFirstLowercaseClassName(EntityClassSchemeInput input) {
    String feignClassName = this.getFeignClassName(input);
    return WordUtils.uncapitalize(feignClassName);
  }

  private String getRestSdkControllerPackageFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format("%s%s", basePackageName, input.getRestSdkControllerPackageSuffix());
  }

  private String getRestSdkControllerClassFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format(
        "%s%s.%s",
        basePackageName,
        input.getRestSdkControllerClassNameSuffix(),
        this.getRestRpcControllerClassName(input));
  }

  private String getRestRpcControllerClassName(EntityClassSchemeInput input) {
    return String.format(
        "%s%s", input.getParams().getSimpleName(), input.getRestSdkControllerClassNameSuffix());
  }

  private String getDtoPackageFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format("%s%s", basePackageName, input.getDtoPackageSuffix());
  }

  private String getApiPackageFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format("%s%s", basePackageName, input.getApiPackageSuffix());
  }

  private String getFeignPackageFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format("%s%s", basePackageName, input.getFeignPackageSuffix());
  }

  private String getFeignApiPackageFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format("%s%s", basePackageName, input.getFeignApiPackageSuffix());
  }

  /**
   * 小写破折号类名
   */
  public String getEntityClassLowercaseDashName(EntityClassSchemeInput input) {
    return ace.cmp.util.CaseFormatUtils.convertUpperCamelToLowerUnderscore(input.getParams().getSimpleName())
        .replaceAll("_", "-");
  }

  private String getNamespace(EntityClassSchemeInput input) {
    return input.getParams().getName().split("\\.")[2];
  }

  private String getApiClassFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format(
        "%s%s.%s", basePackageName, input.getApiPackageSuffix(), this.getApiClassName(input));
  }

  private String getApiClassName(EntityClassSchemeInput input) {
    return String.format("%s%s", input.getParams().getSimpleName(), input.getApiClassNameSuffix());
  }

  private String getDtoClassFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format(
        "%s%s.%s", basePackageName, input.getDtoPackageSuffix(), this.getDtoClassName(input));
  }

  private String getDtoClassName(EntityClassSchemeInput input) {
    return String.format("%s%s", input.getParams().getSimpleName(), input.getDtoClassNameSuffix());
  }

  private String getFeignApiClassFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format(
        "%s%s.%s",
        basePackageName, input.getFeignApiPackageSuffix(), this.getFeignApiClassName(input));
  }

  private String getFeignApiClassName(EntityClassSchemeInput input) {
    return String.format(
        "%s%s", input.getParams().getSimpleName(), input.getFeignApiClassNameSuffix());
  }

  private String getFeignClassFullName(EntityClassSchemeInput input) {
    String basePackageName = GeneratorUtils.getBasePackagePath(input.getParams());
    return String.format(
        "%s%s.%s", basePackageName, input.getFeignPackageSuffix(), this.getFeignClassName(input));
  }

  private String getFeignClassName(EntityClassSchemeInput input) {
    return String.format(
        "%s%s", input.getParams().getSimpleName(), input.getFeignClassNameSuffix());
  }

  private String getEntityIdType(TemplateModel templateModel) {
    return templateModel.getFields().stream()
        .filter(p -> Boolean.TRUE.equals(p.getIdFlag()))
        .findFirst()
        .get()
        .getType()
        .getName();
  }
}
